<template>
  <div class="navigation-page">
    <TopControlBar title="导航" logo-to="/apps">
      <template #center>
        <div style="display: flex; align-items: center; gap: 1rem;">
          <el-button type="primary" @click="handleHeaderCreate">新增导航</el-button>
          <el-input-number v-model="gridColumns" :min="1" :max="10" @change="updateGridColumns"/>
        </div>
      </template>
    </TopControlBar>

    <div class="navigation-content-wrapper">
      <div v-if="loading" class="loading">
        <p>正在加载...</p>
      </div>

      <div v-else-if="navbarTree.length === 0" class="empty-state">
        <h3>暂无导航</h3>
        <p>还没有创建任何导航分类，点击上方"新建导航"按钮来创建第一个分类</p>
      </div>

      <div v-else class="navigation-content">
        <div
            v-for="mainCategory in enabledCategories"
            :key="mainCategory.id"
            class="category-card card-transparent">
          <div class="category-header" :id="`category-${mainCategory.id}`">
            <div class="category-info flex-start gap-sm">
              <span v-if="mainCategory.icon" class="category-icon">{{ mainCategory.icon }}</span>
              <span class="category-title">{{ mainCategory.name }}</span>
            </div>

            <div class="category-controls">
              <div class="category-menu">
                <el-dropdown @command="(command: string) => handleCategoryAction(command, mainCategory)">
                  <el-button text size="small" :icon="More"></el-button>
                  <template #dropdown>
                    <el-dropdown-menu>
                      <el-dropdown-item command="create">新增</el-dropdown-item>
                      <el-dropdown-item command="edit">编辑</el-dropdown-item>
                      <el-dropdown-item command="clone">克隆</el-dropdown-item>
                      <el-dropdown-item command="delete">删除</el-dropdown-item>
                    </el-dropdown-menu>
                  </template>
                </el-dropdown>
              </div>
            </div>
          </div>

          <div class="subcategory-grid" :style="gridStyle">
            <div
                v-for="subCategory in enabledSubCategories(mainCategory)"
                :key="subCategory.id"
                class="sub-category-card card-base">
              <div class="sub-category-header flex-center">
                <div class="sub-category-info flex-start gap-xs">
                  <span v-if="subCategory.icon" class="sub-category-icon">{{ subCategory.icon }}</span>
                  <h3 class="sub-category-title">{{ subCategory.name }}</h3>
                </div>

                <div class="sub-category-menu">
                  <el-dropdown @command="(command: string) => handleSubCategoryAction(command, subCategory)">
                    <el-button text size="small" :icon="More"></el-button>

                    <template #dropdown>
                      <el-dropdown-menu>
                        <el-dropdown-item command="create">新增</el-dropdown-item>
                        <el-dropdown-item command="edit">编辑</el-dropdown-item>
                        <el-dropdown-item command="clone">克隆</el-dropdown-item>
                        <el-dropdown-item command="delete">删除</el-dropdown-item>
                      </el-dropdown-menu>
                    </template>
                  </el-dropdown>
                </div>
              </div>

              <div class="navigation-grid" :data-grid-id="subCategory.id">
                <div
                    v-for="(item, index) in enabledItems(subCategory)"
                    :key="item.id"
                    class="app-wrapper"
                    :data-item-id="item.id"
                >
                  <div
                      class="app-card app-card-base app-card-hover flex-vertical-center gap-sm"
                      :title="item.name"
                      @click="handleItemClick(item)"
                  >
                    <div
                        class="app-icon icon-base icon-medium"
                        :class="{
                      'text-icon': isTextIcon(getFinalIcon(item)),
                      'svg-icon': isSvgIcon(getFinalIcon(item))
                    }"
                        :style="isTextIcon(getFinalIcon(item)) ? getTextIconStyle(getFinalIcon(item)) : {}"
                        :data-category-index="getCategoryIndex(mainCategory)"
                        :data-item-index="index"
                    >
                      <template v-if="isSvgIcon(getFinalIcon(item))">
                        <div v-html="getFinalIcon(item)" class="svg-content"></div>
                      </template>
                      <template v-else>
                        {{ getFinalIcon(item) }}
                      </template>
                    </div>
                    <div class="app-name">{{ item.name }}</div>
                  </div>

                  <div class="app-menu">
                    <el-dropdown @command="(command: string) => handleItemAction(command, item)">
                      <el-button text size="small" :icon="More"></el-button>
                      <template #dropdown>
                        <el-dropdown-menu>
                          <el-dropdown-item command="edit">编辑</el-dropdown-item>
                          <el-dropdown-item command="clone">克隆</el-dropdown-item>
                          <el-dropdown-item command="delete">删除</el-dropdown-item>
                        </el-dropdown-menu>
                      </template>
                    </el-dropdown>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 创建/编辑对话框 -->
    <el-dialog
        v-model="showDialog"
        :title="dialogTitle"
        width="500px"
        @close="closeDialog"
    >
      <el-form @submit.prevent="saveNavbar" label-width="80px">
        <el-form-item label="分类">
          <el-select v-model="form.parentId" placeholder="选择分类" clearable>
            <template v-for="category in enabledCategories" :key="category.id">
              <el-option
                  :value="category.id"
                  :label="(category.icon ? category.icon + ' ' : '') + category.name"
              />
              <template v-for="subCategory in enabledSubCategories(category)" :key="subCategory.id">
                <el-option
                    :value="subCategory.id"
                    :label="'　' + (subCategory.icon ? subCategory.icon + ' ' : '') + subCategory.name"
                />
              </template>
            </template>
          </el-select>
        </el-form-item>

        <el-form-item label="名称" required>
          <el-input
              v-model="form.name"
              placeholder="请输入名称"
              required
          />
        </el-form-item>

        <el-form-item label="链接">
          <el-input
              v-model="form.url"
              type="url"
              placeholder="输入URL链接"
          />
        </el-form-item>

        <el-form-item label="图标">
          <div style="display: flex; flex-direction: column; gap: 12px; width: 100%;">
            <div style="display: flex; gap: 8px;">
              <el-input
                  v-model="form.icon"
                  placeholder="输入文字、图标或SVG代码"
                  style="flex: 1;"
              />
              <el-button @click="form.icon = getRandomIcon()">随机</el-button>
              <el-button @click="showIconSelector = !showIconSelector">
                {{ showIconSelector ? '收起' : '选择' }}
              </el-button>
            </div>

            <div style="font-size: 13px; color: #909399;">
              提示: 需要更多图标？
              <el-link href="https://www.iconfont.cn/" target="_blank" type="primary">
                访问 iconfont.cn 获取图标
              </el-link>
            </div>

            <div v-if="showIconSelector">
              <el-divider>常用图标选择</el-divider>
              <div v-for="(icons, category) in iconCategories" :key="category" style="margin-bottom: 16px;">
                <div style="font-size: 13px; color: #606266; margin-bottom: 8px; font-weight: 500;">
                  {{ category }}
                </div>
                <div style="display: flex; flex-wrap: wrap; gap: 8px;">
                  <el-button
                      v-for="icon in icons"
                      :key="icon"
                      size="small"
                      :type="form.icon === icon ? 'primary' : ''"
                      @click="selectIcon(icon)"
                  >
                    {{ icon }}
                  </el-button>
                </div>
              </div>

              <el-divider>SVG图标</el-divider>
              <el-input
                  v-model="svgInput"
                  type="textarea"
                  :rows="4"
                  placeholder="粘贴SVG代码"
              />
              <div style="display: flex; gap: 8px; margin-top: 8px;">
                <el-button
                    type="primary"
                    size="small"
                    :disabled="!isValidSvg(svgInput)"
                    @click="applySvgIcon"
                >
                  应用SVG
                </el-button>
                <el-button size="small" @click="clearSvgInput">清空</el-button>
              </div>
              <div v-if="svgInput && isValidSvg(svgInput)"
                   style="margin-top: 12px; padding: 12px; background: #f5f7fa; border-radius: 4px; display: flex; align-items: center; gap: 12px;">
                <span style="font-size: 13px; color: #606266;">预览：</span>
                <div v-html="svgInput"
                     style="width: 32px; height: 32px; display: flex; align-items: center; justify-content: center;"></div>
              </div>
            </div>
          </div>
        </el-form-item>

        <el-form-item label="排序号" required>
          <el-input-number v-model="form.sortNo"/>
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button @click="closeDialog">取消</el-button>
        <el-button type="primary" :loading="saving" @click="saveNavbar">
          {{ saving ? '保存中...' : '保存' }}
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import {ref, computed, onMounted, onUnmounted, nextTick} from 'vue'
import type {Navbar, CreateNavbarRequest, UpdateNavbarRequest} from '@/modules/navbar/types/navbar.ts'
import {navbarApi} from '@/modules/navbar/api'
import {toast} from '@/utils'
import {useUserStore} from '@/shared/user.ts'
import Sortable from 'sortablejs'
import TopControlBar from '@/components/TopMenu.vue'
import {More} from "@element-plus/icons-vue";

const userStore = useUserStore()

// 状态
const loading = ref(false)
const saving = ref(false)
const navbarTree = ref<Navbar[]>([])
const showDialog = ref(false)
const editingNavbar = ref<Navbar | null>(null)
const sortableInstances = ref<Map<string, Sortable>>(new Map())
// headerControlsRef 不再需要
const showIconSelector = ref(false)
const svgInput = ref('')

// 网格列数控制
const gridColumns = ref(4)

// 列数选项已不需要，直接使用 el-input-number

// 从localStorage加载网格列数设置
const loadGridColumns = () => {
  const saved = localStorage.getItem('navigation-grid-columns')
  if (saved) {
    const columns = parseInt(saved)
    if (columns >= 1 && columns <= 10) {
      gridColumns.value = columns
    }
  }
}

// 监听网格列数变化
const handleGridColumnsChange = (e: CustomEvent) => {
  const columns = e.detail.columns
  if (columns >= 1 && columns <= 10) {
    gridColumns.value = columns
  }
}

// Header controls methods
const updateGridColumns = () => {
  localStorage.setItem('navigation-grid-columns', gridColumns.value.toString())
  // 派发自定义事件通知其他组件
  window.dispatchEvent(new CustomEvent('navigation-grid-columns-changed', {
    detail: {columns: gridColumns.value}
  }))
}

const handleHeaderCreate = () => {
  if (!userStore.requireLogin()) {
    return
  }
  showCreateDialog()
}

// 精简的渐变色定义（10种核心渐变色）
const textIconColors = [
  {bg: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)', color: '#ffffff'},
  {bg: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)', color: '#ffffff'},
  {bg: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)', color: '#ffffff'},
  {bg: 'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)', color: '#ffffff'},
  {bg: 'linear-gradient(135deg, #fa709a 0%, #fee140 100%)', color: '#ffffff'},
  {bg: 'linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%)', color: '#ffffff'},
  {bg: 'linear-gradient(135deg, #ff9a9e 0%, #fecfef 100%)', color: '#ffffff'},
  {bg: 'linear-gradient(135deg, #a1c4fd 0%, #c2e9fb 100%)', color: '#ffffff'},
  {bg: 'linear-gradient(135deg, #89f7fe 0%, #66a6ff 100%)', color: '#ffffff'},
  {bg: 'linear-gradient(135deg, #fbc2eb 0%, #a6c1ee 100%)', color: '#ffffff'}
]

// 精简的图标选项 
const iconCategories = {
  '分类': ['文件', '档案', '目录', '统计', '机构', '设置'],
  '开发': ['代码', '桌面', '移动', '工具', '构建', '网络', '安全'],
  '社交': ['邮件', '聊天', '通话', '视频', '直播', '录音'],
  '办公': ['文档', '清单', '数据', '编辑', '铅笔', '钢笔'],
  '学习': ['图书', '阅读', '学位', '学校', '研究', '实验'],
  '娱乐': ['游戏', '骰子', '绘画', '音乐', '钢琴', '吉他']
}

// 所有图标的合集
const allIcons = Object.values(iconCategories).flat()

// 表单数据
const form = ref<CreateNavbarRequest>({
  name: '',
  url: '',
  icon: '',
  parentId: null,
  sortNo: 0
})

// 计算属性
const isEditMode = computed(() => !!editingNavbar.value)
const dialogTitle = computed(() => isEditMode.value ? '编辑导航' : '新增导航')
const gridStyle = computed(() => ({'grid-template-columns': `repeat(${gridColumns.value}, 1fr)`}))
const enabledCategories = computed(() => navbarTree.value || [])

// 第二层：获取大分类的children（小分类）
const enabledSubCategories = (mainCategory: Navbar) => mainCategory.children || []

// 第三层：获取小分类的children（导航项）
const enabledItems = (subCategory: Navbar) => subCategory.children || []

// 获取大分类索引（用于设置不同的颜色主题）
const getCategoryIndex = (mainCategory: Navbar) => {
  return enabledCategories.value.findIndex((c: Navbar) => c.id === mainCategory.id)
}

// 生成文字图标
const getTextIcon = (name: string) => {
  if (!name) return ''

  const hasChinese = /[\u4e00-\u9fff]/.test(name)

  if (hasChinese) {
    const chineseChars = name.match(/[\u4e00-\u9fff]/g)
    return chineseChars ? chineseChars.slice(0, 2).join('') : name.slice(0, 2)
  } else {
    const words = name.trim().split(/[\s\-_\.\/\\]+/)
    const firstWord = words[0] || ''
    return firstWord.slice(0, 4).toUpperCase()
  }
}

// 判断是否为文字图标
const isTextIcon = (icon: string) => {
  if (!icon) return false
  return icon.length <= 4 &&
      !icon.includes('<svg')
}

// 根据文本内容生成固定的颜色索引
const getTextIconColorIndex = (text: string) => {
  if (!text) return 0
  let hash = 0
  for (let i = 0; i < text.length; i++) {
    const char = text.charCodeAt(i)
    hash = ((hash << 5) - hash + char) & 0xffffffff
  }
  return Math.abs(hash) % textIconColors.length
}

// 获取文字图标的样式
const getTextIconStyle = (text: string) => {
  const colorIndex = getTextIconColorIndex(text)
  const colorConfig = textIconColors[colorIndex]

  let fontSize = '1.0rem'
  if (text.length === 4) fontSize = '0.8rem'
  else if (text.length === 3) fontSize = '0.9rem'

  return {
    background: colorConfig.bg,
    color: colorConfig.color,
    border: 'none',
    fontSize: fontSize
  }
}

// 获取默认图标
const getDefaultIcon = (name: string) => name ? getTextIcon(name) : ''

// 获取最终显示的图标
const getFinalIcon = (item: any) => {
  if (item.icon && typeof item.icon === 'string' && item.icon.trim()) {
    return item.icon
  }
  return getDefaultIcon(item.name)
}

// 随机选择图标
const getRandomIcon = (): string => {
  const randomIndex = Math.floor(Math.random() * allIcons.length)
  return allIcons[randomIndex]
}

// 选择图标
const selectIcon = (icon: string) => {
  form.value.icon = icon
  showIconSelector.value = false
}

// SVG相关函数
const isValidSvg = (svgCode: string): boolean => {
  if (!svgCode.trim()) return false
  const svgRegex = /<svg[^>]*>[\s\S]*<\/svg>/i
  return svgRegex.test(svgCode.trim())
}

const applySvgIcon = () => {
  if (isValidSvg(svgInput.value)) {
    form.value.icon = svgInput.value.trim()
    showIconSelector.value = false
    svgInput.value = ''
  }
}

const clearSvgInput = () => {
  svgInput.value = ''
}

const isSvgIcon = (icon: string): boolean => {
  if (!icon) return false
  return isValidSvg(icon)
}

// 加载导航数据
const loadNavigation = async () => {
  loading.value = true
  try {
    navbarTree.value = await navbarApi.getAll()
    await nextTick()
    setTimeout(() => {
      initializeSortable()
    }, 100)
  } catch (error) {
    console.error('加载导航失败:', error)
    toast.error('加载导航失败')
  } finally {
    loading.value = false
  }
}

// 初始化拖拽排序
const initializeSortable = () => {
  sortableInstances.value.forEach(instance => instance.destroy())
  sortableInstances.value.clear()

  enabledCategories.value.forEach((mainCategory: Navbar) => {
    enabledSubCategories(mainCategory).forEach((subCategory: Navbar) => {
      const gridElement = document.querySelector(`[data-grid-id="${subCategory.id}"]`)

      if (gridElement) {
        gridElement.classList.add('sortable-enabled')

        const sortable = new Sortable(gridElement as HTMLElement, {
          group: 'navigation-items',
          animation: 150,
          ghostClass: 'sortable-ghost',
          chosenClass: 'sortable-chosen',
          dragClass: 'sortable-drag',
          draggable: '.app-wrapper',
          delay: 100,
          onEnd: async (evt: any) => {
            if (evt.oldIndex !== evt.newIndex || evt.from !== evt.to) {
              await handleSortEnd(evt)
            }
          }
        })
        sortableInstances.value.set(subCategory.id, sortable)
      }
    })
  })
}

// 处理拖拽结束
const handleSortEnd = async (evt: any) => {
  try {
    const fromGridId = evt.from.dataset.gridId
    const toGridId = evt.to.dataset.gridId

    const fromSubCategory = findSubCategoryById(fromGridId)
    const toSubCategory = findSubCategoryById(toGridId)

    if (!fromSubCategory || !toSubCategory) {
      toast.error('无法找到对应的分类')
      return
    }

    const sortUpdates: { id: string, sortNo: number }[] = []

    const toItems = enabledItems(toSubCategory)
    toItems.forEach((item: Navbar, index: number) => {
      const newSortNo = index * 10
      if (item.sortNo !== newSortNo) {
        sortUpdates.push({id: item.id, sortNo: newSortNo})
      }
    })

    if (fromGridId !== toGridId) {
      const fromItems = enabledItems(fromSubCategory)
      fromItems.forEach((item: Navbar, index: number) => {
        const newSortNo = index * 10
        if (item.sortNo !== newSortNo) {
          sortUpdates.push({id: item.id, sortNo: newSortNo})
        }
      })
    }

    if (sortUpdates.length > 0) {
      await navbarApi.updateSort({items: sortUpdates})
      toast.success('排序更新成功')
      await loadNavigation()
    }
  } catch (error: any) {
    console.error('更新排序失败:', error)
    toast.error(error.response?.data?.message || '更新排序失败')
    await loadNavigation()
  }
}

// 根据ID查找小分类
const findSubCategoryById = (id: string): Navbar | null => {
  for (const mainCategory of enabledCategories.value) {
    const subCategory = enabledSubCategories(mainCategory).find((sub: Navbar) => sub.id === id)
    if (subCategory) return subCategory
  }
  return null
}

// 处理导航项点击
const handleItemClick = (item: Navbar) => {
  if (item.url) {
    window.open(item.url, '_blank', 'noopener,noreferrer')
  }
}

// 显示创建对话框
const showCreateDialog = () => {
  editingNavbar.value = null
  form.value = {
    name: '',
    url: '',
    icon: '',
    parentId: null,
    sortNo: 0
  }
  showDialog.value = true
}

// 显示创建对话框并预选父级分类
const showCreateDialogWithParent = (parentId: string) => {
  editingNavbar.value = null
  form.value = {
    name: '',
    url: '',
    icon: '',
    parentId: parentId,
    sortNo: 0
  }
  showDialog.value = true
}

// 处理大分类操作
const handleCategoryAction = (action: string, category: Navbar) => {
  switch (action) {
    case 'create':
      showCreateDialogWithParent(category.id)
      break
    case 'edit':
      editNavbar(category)
      break
    case 'clone':
      cloneNavbar(category)
      break
    case 'delete':
      deleteNavbar(category)
      break
  }
}

// 处理子分类操作
const handleSubCategoryAction = (action: string, subCategory: Navbar) => {
  switch (action) {
    case 'create':
      showCreateDialogWithParent(subCategory.id)
      break
    case 'edit':
      editNavbar(subCategory)
      break
    case 'clone':
      cloneNavbar(subCategory)
      break
    case 'delete':
      deleteNavbar(subCategory)
      break
  }
}

// 处理项目操作
const handleItemAction = (action: string, item: Navbar) => {
  switch (action) {
    case 'edit':
      editNavbar(item)
      break
    case 'clone':
      cloneNavbar(item)
      break
    case 'delete':
      deleteNavbar(item)
      break
  }
}

// 编辑导航
const editNavbar = async (navbar: Navbar) => {

  try {
    const navbarDetail = await navbarApi.getById(navbar.id)
    editingNavbar.value = navbarDetail

    const parentId = findParentId(navbar.id)

    form.value = {
      name: navbarDetail.name,
      url: navbarDetail.url || '',
      icon: navbarDetail.icon || '',
      parentId: parentId,
      sortNo: navbarDetail.sortNo || 0
    }
    showDialog.value = true
  } catch (error: any) {
    console.error('获取导航详情失败:', error)
    toast.error(error.response?.data?.message || '获取导航详情失败')
  }
}

// 克隆导航
const cloneNavbar = async (navbar: Navbar) => {

  try {
    const navbarDetail = await navbarApi.getById(navbar.id)
    const parentId = findParentId(navbar.id)

    editingNavbar.value = null

    form.value = {
      name: `${navbarDetail.name}（副本）`,
      url: navbarDetail.url || '',
      icon: navbarDetail.icon || '',
      parentId: parentId,
      sortNo: (navbarDetail.sortNo || 0) + 1
    }

    showDialog.value = true

  } catch (error: any) {
    console.error('获取导航详情失败:', error)
    toast.error(error.response?.data?.message || '获取导航详情失败')
  }
}

// 查找项目的父级ID
const findParentId = (itemId: string): string | null => {
  const isTopLevel = navbarTree.value.some(item => item.id === itemId)
  if (isTopLevel) return null

  for (const category of navbarTree.value) {
    const isSecondLevel = category.children?.some((child: Navbar) => child.id === itemId)
    if (isSecondLevel) return category.id

    if (category.children) {
      for (const subCategory of category.children) {
        const isThirdLevel = subCategory.children?.some((child: Navbar) => child.id === itemId)
        if (isThirdLevel) return subCategory.id
      }
    }
  }

  return null
}

// 保存导航
const saveNavbar = async () => {
  saving.value = true
  try {
    const finalIcon = form.value.icon || ''

    if (isEditMode.value && editingNavbar.value) {
      const updateData: UpdateNavbarRequest = {
        name: form.value.name,
        url: form.value.url || null,
        icon: finalIcon,
        parentId: form.value.parentId,
        sortNo: form.value.sortNo
      }
      await navbarApi.update(editingNavbar.value.id, updateData)
      toast.success('更新成功')
    } else {
      const createData: CreateNavbarRequest = {
        name: form.value.name,
        url: form.value.url || null,
        icon: finalIcon,
        parentId: form.value.parentId,
        sortNo: form.value.sortNo
      }
      await navbarApi.create(createData)
      toast.success('创建成功')
    }

    closeDialog()
    await loadNavigation()
  } catch (error: any) {
    console.error('保存失败:', error)
    toast.error(error.response?.data?.message || '保存失败')
  } finally {
    saving.value = false
  }
}

// 删除导航
const deleteNavbar = async (navbar: Navbar) => {
  const hasChildren = navbar.children && navbar.children.length > 0

  if (hasChildren) {
    toast.warning(`该项目下还有子项，请先删除子项`)
    return
  }

  const message = `确定要删除"${navbar.name}"吗？`

  const confirmed = await toast.confirm(message, {
    title: '确认删除',
    confirmButtonText: '删除',
    cancelButtonText: '取消'
  })

  if (!confirmed) return


  try {
    await navbarApi.delete(navbar.id)
    toast.success('删除成功')
    await loadNavigation()
  } catch (error: any) {
    console.error('删除失败:', error)
    toast.error(error.response?.data?.message || '删除失败')
  }
}

// 关闭对话框
const closeDialog = () => {
  showDialog.value = false
  editingNavbar.value = null
  showIconSelector.value = false
  svgInput.value = ''
  form.value = {
    name: '',
    url: '',
    icon: '',
    parentId: null,
    sortNo: 0
  }
}

// 初始化
onMounted(() => {
  document.title = '懒熊导航'
  loadGridColumns()
  window.addEventListener('navigation-grid-columns-changed', handleGridColumnsChange as EventListener)
  loadNavigation()
})

onUnmounted(() => {
  window.removeEventListener('navigation-grid-columns-changed', handleGridColumnsChange as EventListener)
  sortableInstances.value.forEach(instance => instance.destroy())
  sortableInstances.value.clear()
})
</script>

<style scoped>
.navigation-page {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: #FFFFFF;
}

/* Header 样式已移到 TopControlBar 组件 */

/* 内容区域 */
.navigation-content-wrapper {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: auto;
  padding: 1rem;
  margin-top: 64px; /* 为固定的顶部菜单留出空间 */
}

.loading, .empty-state {
  text-align: center;
  color: white;
  padding: 4rem;
}

.navigation-content {
  max-width: none;
  display: flex;
  flex-direction: column;
  gap: 0.5em;
}

/* category-card 样式已移到公共样式 card-transparent */

.category-header {
  margin: 0;
  padding: 0;
  line-height: 1;
  display: flex;
  justify-content: space-between;
}

.category-icon {
  font-size: 2.5rem;
}

.category-title {
  margin: 0 !important;
  padding: 0 !important;
  color: #2c3e50;
  font-size: 14px;
  line-height: 1;
}

.category-description {
  color: #666;
  margin-bottom: 0;
  font-size: 1rem;
}

.subcategory-grid {
  display: grid;
  gap: 1rem;
  margin-top: 0;
}

@media (max-width: 768px) {
  .subcategory-grid {
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)) !important;
  }
}

/* sub-category-card 样式已移到公共样式 card-base */

.sub-category-header {
  margin-bottom: 0.5rem;
  position: relative;
}

/* sub-category-info 样式已移到公共样式 flex-start gap-xs */

.sub-category-icon {
  font-size: 1.2rem;
}

.sub-category-title {
  margin: 0;
  color: #34495e;
  font-size: 14px;
  font-weight: 500;
}

.sub-category-menu {
  position: absolute;
  top: 0;
  right: 0;
  opacity: 0;
  transition: opacity 0.2s;
}

.sub-category-card:hover .sub-category-menu {
  opacity: 1;
}

.sub-category-menu .menu-trigger-btn {
  padding: 4px 8px;
  min-height: auto;
  font-size: 16px;
  color: #999;
}

.sub-category-menu .menu-trigger-btn:hover {
  color: #666;
  background: #f0f0f0;
}

.category-menu, .app-menu {
  position: relative;
}

.category-menu {
  opacity: 0;
  transition: opacity 0.2s;
}

.category-header:hover .category-menu {
  opacity: 1;
}

.category-menu .el-button {
  padding: 4px 8px;
  min-height: auto;
  font-size: 16px;
  color: #999;
}

.category-menu .el-button:hover {
  color: #666;
  background: #f0f0f0;
}

.app-menu {
  position: absolute;
  top: -6px;
  right: 2px;
  z-index: 10;
  opacity: 0;
  transition: opacity 0.2s;
}

.app-wrapper:hover .app-menu {
  opacity: 1;
}

.app-menu .el-button {
  background: rgba(255, 255, 255, 0.9);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  padding: 2px 4px;
  min-height: auto;
  font-size: 12px;
  color: #999;
}

.app-menu .el-button:hover {
  color: #666;
  background: #f0f0f0;
}

.app-menu .el-button .el-icon {
  font-size: 14px;
}

/* 菜单相关样式已移到公共样式：menu-trigger-base, dropdown-menu-base, menu-item-base, menu-item-danger */
.navigation-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
}

.sub-category-card .navigation-grid {
  grid-template-columns: repeat(auto-fill, minmax(60px, 1fr));
  gap: 0.5rem;
}

.app-wrapper {
  position: relative;
  cursor: grab;
  transition: all 0.2s ease;
}

.app-wrapper:hover {
  cursor: grab;
  transform: translateY(-2px);
}

.app-wrapper:active {
  cursor: grabbing;
}

/* app-card 基础样式已移到公共样式 app-card-base, app-card-hover */
.app-card {
  padding: 0.75rem 0.25rem;
}

.app-card:hover .app-icon {
  transform: translateY(-2px) scale(1.05);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15),
  0 4px 12px rgba(0, 0, 0, 0.1);
}

.app-card:hover .app-name {
  color: #2d3748;
  transform: translateY(-1px);
}

/* app-icon 基础样式已移到公共样式 icon-base icon-large, 子分类的为 icon-medium */

.app-icon.text-icon {
  font-size: 1.0rem;
  font-weight: 700;
  letter-spacing: -0.02em;
}

/* 不同分类的配色方案（仅适用于非文字图标，包括SVG图标） */
.app-icon[data-category-index="0"]:not(.text-icon) {
  background: linear-gradient(145deg, #667eea 0%, #764ba2 100%);
  color: white;
}

.app-icon[data-category-index="1"]:not(.text-icon) {
  background: linear-gradient(145deg, #ff6b6b 0%, #ff8e53 100%);
  color: white;
}

.app-icon[data-category-index="2"]:not(.text-icon) {
  background: linear-gradient(145deg, #4ecdc4 0%, #44a08d 100%);
  color: white;
}

.app-icon[data-category-index="3"]:not(.text-icon) {
  background: linear-gradient(145deg, #45b7d1 0%, #96c93d 100%);
  color: white;
}

.app-icon[data-category-index="4"]:not(.text-icon) {
  background: linear-gradient(145deg, #f093fb 0%, #f5576c 100%);
  color: white;
}

.app-icon[data-category-index="5"]:not(.text-icon) {
  background: linear-gradient(145deg, #ffecd2 0%, #fcb69f 100%);
  color: #8b5a3c;
}

.app-name {
  font-size: 0.75rem;
  color: #2c3e50;
  text-align: center;
  font-weight: 500;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 0 0.125rem;
  transition: color 0.3s;
}

.sub-category-card .app-card {
  gap: 0.375rem;
  padding: 0.5rem 0.125rem;
}

.sub-category-card .app-icon {
  width: 48px;
  height: 48px;
  font-size: 1.4rem;
  border-radius: 12px;
}

.sub-category-card .app-icon.text-icon {
  font-size: 1rem;
  font-weight: 700;
}

.sub-category-card .app-name {
  font-size: 0.6875rem;
  padding: 0;
}

.app-icon.svg-icon {
  /* SVG图标也使用随机背景色，不再设置为透明 */
  border: none;
}

.app-icon .svg-content {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.app-icon .svg-content svg {
  max-width: 32px;
  max-height: 32px;
}

/* 拖拽相关样式 */
.sortable-ghost {
  opacity: 0.4;
  transform: scale(0.95);
}

.sortable-chosen {
  cursor: grabbing !important;
}

.sortable-drag {
  cursor: grabbing !important;
  transform: rotate(3deg);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3) !important;
  z-index: 1000;
}

.navigation-grid .app-wrapper.sortable-chosen .app-card,
.navigation-grid .app-wrapper.sortable-drag .app-card {
  background: rgba(102, 126, 234, 0.1);
  border: 3px dashed #667eea;
}

/* 移动端适配 */
@media (max-width: 768px) {
  .navigation-content-wrapper {
    padding: 1rem;
  }
}

/* 响应式设计 */
@media (max-width: 768px) {

  .navigation-grid {
    grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
    gap: 0.5rem;
  }

  .app-icon {
    width: 48px;
    height: 48px;
    font-size: 1.5rem;
    border-radius: 12px;
  }

  .app-name {
    font-size: 0.6875rem;
  }

  .sub-category-card .navigation-grid {
    grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));
    gap: 0.375rem;
    padding: 0.125rem;
  }

  .sub-category-card .app-icon {
    width: 40px;
    height: 40px;
    font-size: 1.2rem;
    border-radius: 8px;
  }

  .sub-category-card .app-name {
    font-size: 0.625rem;
  }

  .app-menu .menu-trigger,
  .category-menu .menu-trigger {
    opacity: 1;
  }
}

/* 深色模式 */
/* 深色模式样式已移动到 dark-theme.css */

</style>